// -----------------------------------------------------------------------
//  <copyright file="ApiResultExceptionHandlerBase.cs" company="LiuliuSoft">
//      Copyright (c) 2022-2024 DaprPlus. All rights reserved.
//  </copyright>
//  <site>https://dapr.plus</site>
//  <last-editor>郭明锋</last-editor>
//  <last-date>2024/12/8 3:02:06</last-date>
// -----------------------------------------------------------------------

using DaprPlus.AspNetCore.Extensions;
using DaprPlus.Domain;

using Microsoft.AspNetCore.Mvc.Filters;

namespace DaprPlus.AspNetCore.Mvc.Filters;

/// <summary>
/// API结果异常处理器基类
/// </summary>
public abstract class ApiResultExceptionHandlerBase : IApiResultExceptionHandler
{
    /// <inheritdoc />
    public abstract int Priority { get; }

    /// <inheritdoc />
    public abstract bool CanHandle(Exception exception);

    /// <inheritdoc />
    public virtual bool Handle(Exception exception, ActionExecutedContext context)
    {
        // 默认只处理JSON/AJAX请求
        if (!context.HttpContext.Request.IsJsonContextType() && !context.HttpContext.Request.IsAjaxRequest())
        {
            return false;
        }

        var message = GetFriendlyMessage(exception);
        return SetJsonErrorResult(context, message);
    }

    /// <summary>
    /// 获取友好的错误消息
    /// </summary>
    /// <param name="exception">异常对象</param>
    /// <returns>友好的错误消息</returns>
    protected abstract string GetFriendlyMessage(Exception exception);

    /// <summary>
    /// 设置JSON错误结果
    /// </summary>
    /// <param name="context">Action执行上下文</param>
    /// <param name="message">错误消息</param>
    /// <param name="resultType">结果类型</param>
    /// <returns>是否设置成功</returns>
    protected virtual bool SetJsonErrorResult(ActionExecutedContext context, string message, ApiResultType resultType = ApiResultType.Error)
    {
        if (!context.HttpContext.Response.HasStarted)
        {
            var result = new ApiResult(message, resultType);
            context.Result = result.ToActionResult();
        }
        context.ExceptionHandled = true;
        return true;
    }

    /// <summary>
    /// 设置HTTP状态码
    /// </summary>
    /// <param name="context">Action执行上下文</param>
    /// <param name="statusCode">HTTP状态码</param>
    /// <returns>是否设置成功</returns>
    protected virtual bool SetHttpStatusCode(ActionExecutedContext context, int statusCode)
    {
        context.HttpContext.Response.StatusCode = statusCode;
        context.ExceptionHandled = true;
        return true;
    }
}
